<?php

/*
 * Copyright 2008 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#namespace tehframework\validation;

/**
 * Encapsulates a field error, that is, a reason for rejecting a specific
 * field value.
 */
class FieldError extends ObjectError
{
	/**
	 * @var string
	 */
	private $field;
	
	/**
	 * @var mixed
	 */
	private $rejectedValue;
	
	/**
	 * @var bool
	 */
	private $bindingFailure;


	/**
	 * Create a new FieldError instance.
	 * 
	 * @param  string $objectName
	 *         The name of the affected object.
	 * @param  string $field
	 *         The affected field of the object.
	 * @param  mixed $rejectedValue
	 *         The rejected field value.
	 * @param  bool $bindingFailure
	 *         Whether this error represents a binding failure
	 *         (like a type mismatch); else, it is a validation failure.
	 * @param  array<string>? $codes
	 *         The codes to be used to resolve this message.
	 * @param  array? $arguments
	 *         The array of arguments to be used to resolve this message.
	 * @param  string? $defaultMessage
	 *         The default message to be used to resolve this message.
	 * @throws IllegalArgumentException
	 *         If the supplied $field is NULL or empty.
	 * @throws IllegalArgumentException
	 *         If the supplied $objectName is NULL or empty.
	 */
	public function __construct(
		$objectName,
		$field,
		$rejectedValue,
		$bindingFailure = false,
		array $codes = null,
		array $arguments = null,
		$defaultMessage = null)
	{
		if (($field === null) || (trim($field) === ''))
		{
			throw new InvalidArgumentException('Field must not be NULL nor empty.');
		}
		
		parent::__construct($objectName, $codes, $arguments, $defaultMessage);
		
		$this->field          = $field;
		$this->rejectedValue  = $rejectedValue;
		$this->bindingFailure = (bool)$bindingFailure;
	}
	
	/**
	 * @return string
	 */
	public function __toString()
	{
		return "Field error in object '" . $this->getObjectName() . "' on field '" .
			$this->field . "': rejected value [" . this.rejectedValue . "]; " .
			$this->resolvableToString();
	}
	
	/**
	 * Returns the affected field of the object.
	 * 
	 * @return string
	 *         The affected field of the object.
	 */
	public function getField()
	{
		return $this->field;
	}
	
	/**
	 * Returns the rejected field value.
	 * 
	 * @return mixed
	 *         The rejected field value.
	 */
	public function getRejectedValue()
	{
		return $this->rejectedValue;
	}
	
	/**
	 * Determines whether this error represents a binding failure
	 * (like a type mismatch); else, it is a validation failure.
	 * 
	 * @return bool
	 *         TRUE if this error represents a binding failure;
	 *         otherwise FALSE, a validation failure.
	 */
	public function isBindingFailure()
	{
		return $this->bindingFailure;
	}
}